﻿#include "DataPackage_UdpCodec.h"

#include <qnetworkdatagram.h>

DataPackage_UdpCodec::DataPackage_UdpCodec() : QObject()
{

}

DataPackage_UdpCodec::DataPackage_UdpCodec(const DataPackage_UdpCodec& dataPackageInfo)
{
  *this=dataPackageInfo;
}

DataPackage_UdpCodec &DataPackage_UdpCodec::operator=(const DataPackage_UdpCodec &dataPackageInfo)
{
  senderAddress=dataPackageInfo.senderAddress;
  senderPort=dataPackageInfo.senderPort;
  receiverAddress=dataPackageInfo.receiverAddress;
  receiverPort=dataPackageInfo.receiverPort;
  deviceId=dataPackageInfo.deviceId;
  packageType=dataPackageInfo.packageType;
  msgId=dataPackageInfo.msgId;
  timeStamp=dataPackageInfo.timeStamp;
  data=dataPackageInfo.data;
  return *this;
}

DataPackage_UdpCodec::~DataPackage_UdpCodec()
{}

DataPackage_UdpCodec *DataPackage_UdpCodec::toAck(QByteArray data)
{
  setReceiverAddress(senderAddress);
  setReceiverPort(senderPort);
  setData(data);
  return this;
}

QNetworkDatagram* DataPackage_UdpCodec::toNetworkDatagram()
{
  QNetworkDatagram * qNetworkDatagram=new QNetworkDatagram();
  QByteArray temp;
  temp.append(packageType);
  temp.append((char*)&msgId,2);
  temp.append((char*)&deviceId,4);
  temp.append((char*)&timeStamp,2);
  temp.append(data);
  qNetworkDatagram->setDestination(QHostAddress(receiverAddress),receiverPort);
  qNetworkDatagram->setData(temp);
  return qNetworkDatagram;
}

DataPackage_UdpCodec* DataPackage_UdpCodec::fromNetworkDatagram(QNetworkDatagram *qNetworkDatagram)
{
  int dataSize=qNetworkDatagram->data().size();
  QByteArray data=qNetworkDatagram->data();
  char* dataPtr=data.data();
  if(dataSize<dataHeadSize||maxDataSize<dataSize)
    {
      return Q_NULLPTR;
    }
  int dataPtrOffset=0;
  DataPackage_UdpCodec* dataPackageInfo=new DataPackage_UdpCodec();
  //解析数据
  dataPackageInfo->setPackageType(decode<uchar>(dataPtr,&dataPtrOffset));
  dataPackageInfo->setMsgId(decode<ushort>(dataPtr,&dataPtrOffset));
  dataPackageInfo->setDeviceId(decode<uint>(dataPtr,&dataPtrOffset));
  dataPackageInfo->setTimeStamp(decode<ushort>(dataPtr,&dataPtrOffset));
  dataPackageInfo->setData(QByteArray(dataPtr+dataPtrOffset,dataSize-dataPtrOffset));
  //填入一般参数
  dataPackageInfo->setSenderAddress(qNetworkDatagram->senderAddress().toIPv4Address());//发送者IP地址
  dataPackageInfo->setSenderPort(qNetworkDatagram->senderPort());//发送者端口
  dataPackageInfo->setReceiverAddress(qNetworkDatagram->destinationAddress().toIPv4Address());//接收者IP地址
  dataPackageInfo->setReceiverPort(qNetworkDatagram->destinationPort());//接收者端口
  return dataPackageInfo;
}

uint DataPackage_UdpCodec::hashValue()
{
  return hashValue(deviceId,
                   packageType,
                   msgId);
}

uint DataPackage_UdpCodec::hashValue(DataPackage_UdpCodec* dataPackage_UdpCodec)
{
  return hashValue(dataPackage_UdpCodec->deviceId,
                   dataPackage_UdpCodec->packageType,
                   dataPackage_UdpCodec->msgId);
}

uint DataPackage_UdpCodec::hashValue(uint deviceId,
                                     uchar packageType,
                                     ushort msgId)
{
  return qHash(deviceId+qHash(packageType+qHash(msgId,1),2),3);
}

template<class T>T DataPackage_UdpCodec::decode(char* dataPtr,int* dataPtrOffset)
{
  T* temp=(T*)(dataPtr+*dataPtrOffset);
  *dataPtrOffset+=sizeof (T);
  return *temp;
}

uint DataPackage_UdpCodec::getSenderAddress()
{
  return senderAddress;
}

DataPackage_UdpCodec* DataPackage_UdpCodec::setSenderAddress(uint senderAddress)
{
  this->senderAddress=senderAddress;
  return this;
}

ushort DataPackage_UdpCodec::getSenderPort()
{
  return senderPort;
}

DataPackage_UdpCodec* DataPackage_UdpCodec::setSenderPort(ushort senderPort)
{
  this->senderPort=senderPort;
  return this;
}

uint DataPackage_UdpCodec::getReceiverAddress()
{
  return receiverAddress;
}

DataPackage_UdpCodec* DataPackage_UdpCodec::setReceiverAddress(uint receiverAddress)
{
  this->receiverAddress=receiverAddress;
  return this;
}

uint DataPackage_UdpCodec::getReceiverPort()
{
  return receiverPort;
}

DataPackage_UdpCodec* DataPackage_UdpCodec::setReceiverPort(uint receiverPort)
{
  this->receiverPort=receiverPort;
  return this;
}

uint DataPackage_UdpCodec::getDeviceId()
{
  return deviceId;
}

DataPackage_UdpCodec* DataPackage_UdpCodec::setDeviceId(uint deviceId)
{
  this->deviceId=deviceId;
  return this;
}

uchar DataPackage_UdpCodec::getPackageType()
{
  return packageType;
}

DataPackage_UdpCodec* DataPackage_UdpCodec::setPackageType(uchar packageType)
{
  this->packageType=packageType;
  return this;
}

ushort DataPackage_UdpCodec::getMsgId()
{
  return msgId;
}
DataPackage_UdpCodec* DataPackage_UdpCodec::setMsgId(ushort msgId)
{
  this->msgId=msgId;
  return this;
}

ushort DataPackage_UdpCodec::getTimeStamp()
{
  return timeStamp;
}

DataPackage_UdpCodec* DataPackage_UdpCodec::setTimeStamp(ushort timeStamp)
{
  this->timeStamp=timeStamp;
  return this;
}

QByteArray DataPackage_UdpCodec::getData()
{
  return data;
}
DataPackage_UdpCodec* DataPackage_UdpCodec::setData(QByteArray data)
{
  this->data=data;
  return this;
}


